<?php

namespace App\V3\V3_2\Services;

use App\V3\V3_2\Models\LogInStorageModel;
use App\V3\V3_2\Models\MaterielContentModel;
use App\V3\V3_2\Models\MaterielModel;
use App\V3\V3_2\Models\MaterielOtherChargesModel;
use App\V3\V3_2\Models\MaterielsTypeModel;
use App\V3\V3_2\Models\SellMaterielPrepareOutLogModel;
use App\V3\V3_2\Models\StorageBatchModel;
use App\V3\V3_2\Models\StorageManageModel;
use App\V3\V3_2\Models\StorageModel;
use App\V3\V3_2\Models\SupplierCustomerModel;
use App\V3\V3_2\Models\CheckModel;
use App\V3\V3_2\Models\MaterielPayHistoryModel;
use App\V3\V3_2\Models\TallyClassModel;
use App\V3\V3_2\Models\TallyModel;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\V3\V3_2\Models\MaterielSerialNumberModel;
use App\V3\V3_2\Models\SerialNumberModel;

class MaterielService
{
    static public function edit($data)
    {
        $materielContent = json_decode($data['materiel_content'], true);
        unset($data['materiel_content']);

        $data['purchase_time'] = empty($data['purchase_time'])?time():strtotime($data['purchase_time']);

        $newMaterielTypeId = [];//新采购单内容物料id
        $data['original_money'] = 0;//税前应付应付金额
        foreach($materielContent as $value) {
            $newMaterielTypeId[] = $value['type_id'];

            $data['original_money'] += $value['num'] * $value['unit_price'];
        }

        foreach($materielContent as $k => $v) {
            $storageInfo = StorageModel::where('id', $v['storage_id'])
                ->where('main_id', $data['main_id'])
                ->where('delete_flag', 0)
                ->first();

            if(empty($storageInfo)) {
                return ['code' => 0, 'msg' => '仓库不存在', 'data' => ''];
            }

            $materielContent[$k]['storage_name'] = $storageInfo['storage_name'];
            $materielContent[$k]['storage_address'] = $storageInfo['storage_address'];
        }

        //应付金额(税后)
        $data['real_money'] = $data['tax_rate'] == 0?$data['original_money']:$data['original_money'] * ($data['tax_rate'] / 100) + $data['original_money'];
        /**
         * @preferential_way:优惠方式;0:无;1:修改价格;2:折扣优惠;
         * 优惠方式为非0值时，实付金额为修改后的金额或折扣优惠后的金额
         */
        switch($data['preferential_way']) {
            case 0:
                $data['final_money'] = $data['real_money'];
                break;
            case 1:
                $data['final_money'] = $data['preferential_money'];
                break;
            case 2:
                if($data['preferential_money'] >= 100) {
                    return ['code' => 0, 'msg' => '折扣比例不能超出百分百', 'data' => ''];
                }
                //折扣后
                $afterDiscount = ($data['original_money'] * ($data['preferential_money'] / 100));
                //税后
                $afterTaxRate = $afterDiscount + ($afterDiscount * ($data['tax_rate'] / 100));
                $data['final_money'] = ceil($afterTaxRate * 100) / 100;//物料均价
                $data['discount'] = $data['preferential_money'];
                break;
        }

        unset($data['preferential_money']);

        $materielContentInfo = MaterielContentModel::where('materiel_id', $data['id'])->get()->toArray();

        $uselessContentId = [];//修改后无用的采购内容id
        $needsToUpdate = [];
        $existMaterielContentTypeId = [];
        foreach($materielContentInfo as $kk => $val) {
            //已有采购内容发生替换
            if(!in_array($val['type_id'], $newMaterielTypeId)) {
                $uselessContentId[] = $val['id'];
            }
            else {
                $existMaterielContentTypeId[] = $val['type_id'];
                $v['purchase_time'] = $data['purchase_time'];

                foreach($materielContent as $k3 => $v3) {
                    if($val['type_id'] == $v3['type_id']) {
                        $v3['id'] = $val['id'];
                        $v3['materiel_id'] = $data['id'];
                        $v3['user_id'] = $data['user_id'];
                        $v3['remark'] = !empty($data['remark'])?$data['remark']:"";
                        $v3['main_id'] = $data['main_id'];
                        $v3['created_at'] = time();
                        $v3['rest_num'] = $v3['num'];
                        $v3['purchase_time'] = !empty($data['purchase_time'])?$data['purchase_time']:"";
                        $needsToUpdate[$k3] = $v3;
                    }
                }
            }
        }

        $needsToInsert = [];
        foreach($materielContent as $k => $v) {
            if(!in_array($v['type_id'], $existMaterielContentTypeId)) {
                $v['materiel_id'] = $data['id'];
                $v['user_id'] = $data['user_id'];
                $v['main_id'] = $data['main_id'];
                $v['created_at'] = time();
                $v['rest_num'] = $v['num'];
                $v['purchase_time'] = $data['purchase_time'];
                $needsToInsert[] = $v;
            }
        }

        unset($data['main_id']);
        unset($data['user_id']);

        $supplierInfo = SupplierCustomerModel::where('id', $data['supplier_customer_id'])->first();
        $data['supplier_customer_id'] = $supplierInfo['id'];
        $data['deliver_person'] = empty($data['deliver_person'])?$supplierInfo['name']:$data['deliver_person'];
        $data['deliver_phone'] = empty($data['deliver_phone'])?$supplierInfo['phone']:$data['deliver_phone'];
        $data['deliver_address'] = empty($data['deliver_address'])?$supplierInfo['address']:$data['deliver_address'];
        $data['supplier_name'] = $supplierInfo['name'];

        $materielInfo = MaterielModel::where('id', $data['id'])->first();

        if($materielInfo['pay_status'] != 0) {
            unset($data['fact_money']);
        }

        DB::beginTransaction();

        try {
            //删除无用采购内容
            MaterielContentModel::whereIn('id', $uselessContentId)->delete();
            MaterielModel::where('id', $data['id'])->lockForUpdate()->update($data);
            MaterielContentModel::insert($needsToInsert);
            foreach($needsToUpdate as $k2 => $v2) {
                $v2['purchase_time'] = $data['purchase_time'];
                $v2['rest_num'] = $v2['num'];
                MaterielContentModel::where('id', $v2['id'])->lockForUpdate()->update($v2);
            }
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        } catch (Exception $e) {
            DB::rollBack();
            Log::debug('修改采购单:'.var_export($e->getMessage(), true));
        }
    }

    static public function add($data)
    {
        DB::beginTransaction();

        try {
            $materielContent = json_decode($data['materiel_content'], true);
            unset($data['materiel_content']);

            //原金额(税前应付)
            $data['original_money'] = 0;
            foreach($materielContent as $value)
            {
                $data['original_money'] += $value['unit_price'] * $value['num'];
            }

            //应付金额(修改价格或折扣优惠前金额)
            $data['real_money'] = $data['original_money'] + ($data['original_money'] * ($data['tax_rate'] / 100));

            /**
             * @preferential_way:优惠方式;0:无;1:修改价格;2:折扣优惠;
             * 优惠方式为非0值时，实付金额为修改后的金额或折扣优惠后的金额
             */
            switch($data['preferential_way']) {
                case 0:
                    $data['final_money'] = $data['real_money'];
                    break;
                case 1:
                    $data['final_money'] = $data['preferential_money'];
                    break;
                case 2:
                    if($data['preferential_money'] >= 100) {
                        return ['code' => 0, 'msg' => '折扣比例不能超出百分百', 'data' => ''];
                    }
                    //折扣后
                    $afterDiscount = ($data['original_money'] * ($data['preferential_money'] / 100));
                    //税后
                    $afterTaxRate = $afterDiscount + ($afterDiscount * ($data['tax_rate'] / 100));
                    $data['final_money'] = ceil($afterTaxRate * 100) / 100;//物料均价
                    $data['discount'] = $data['preferential_money'];
                    break;
            }

            unset($data['preferential_money']);

            $data['remark'] = empty($data['remark'])?'':$data['remark'];
            $data['purchase_time'] = empty($data['purchase_time'])?time():strtotime($data['purchase_time']);
            $data['created_at'] = time();

            $supplierInfo = SupplierCustomerModel::where('id', $data['supplier_customer_id'])->first();
            $data['supplier_customer_id'] = $supplierInfo['id'];
            $data['deliver_person'] = $supplierInfo['name'];
            $data['deliver_phone'] = $supplierInfo['phone'];
            $data['deliver_address'] = $supplierInfo['address'];
            $data['supplier_name'] = $supplierInfo['name'];

            foreach($materielContent as $k => $v) {
                $storageInfo = StorageModel::where('id', $v['storage_id'])
                    ->where('main_id', $data['main_id'])
                    ->where('delete_flag', 0)
                    ->first();

//                if(empty($storageInfo)) {
//                    return ['code' => 0, 'msg' => '仓库不存在', 'data' => ''];
//                }

                $materielTypeInfo = MaterielsTypeModel::where('id', $v['type_id'])->first();

                $materielContent[$k]['materiel_name'] = $materielTypeInfo['materiel_name'];
                $materielContent[$k]['type_name'] = $materielTypeInfo['type_name'];
                $materielContent[$k]['materiel_img'] = empty($materielTypeInfo['materiel_img'])?'':$materielTypeInfo['materiel_img'];
                $materielContent[$k]['materiel_no'] = $materielTypeInfo['materiel_no'];
                $materielContent[$k]['storage_name'] = $storageInfo['storage_name'];
                $materielContent[$k]['storage_address'] = $storageInfo['storage_address'];
                $materielContent[$k]['remark'] = empty($v['remark'])?'':$v['remark'];
            }

            $insertId = MaterielModel::insertGetId($data);
            CheckModel::insert([
                'type' => 3,
                'all_id' => $insertId,
                'main_id' => $data['main_id'],
                'user_id' => $data['user_id'],
                'status' => 0,
                'out_in_status' => 0,
                'order_no' => $data['purchase_no'],
                'remark' => $data['remark'],
                'created_at' => time(),
            ]);

            $res = self::addMaterielContent($materielContent, $insertId, $data['user_id'], $data['main_id'], $data['purchase_time']);
            if($res['code'] == 1) return $res;
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ['id' => $insertId]];
            //其他金额累加到实付和应付内
        } catch (Exception $e) {
            DB::rollBack();
            Log::debug('创建采购:'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //添加套餐内容
    static public function addMaterielContent($materielContent, $materielId, $userId, $parentId, $purchaseTime)
    {
        foreach($materielContent as $key => $value) {
            if(empty($value['type_id'])) {
                return ['code' => 1, 'msg' => '请选择物料产品', 'data' => ''];
            }

            if(empty($value['materiel_name'])) {
                return ['code' => 1, 'msg' => '物料名称缺失', 'data' => ''];
            }

//            if(empty($value['type_name'])) {
//                return ['code' => 1, 'msg' => '物料型号缺失', 'data' => ''];
//            }

            if(empty($value['storage_id'])) {
                return ['code' => 1, 'msg' => '请选择入库目标仓库', 'data' => ''];
            }

            if(!isset($value['unit_price'])) {
                return ['code' => 1, 'msg' => '请填写物料单价', 'data' => ''];
            }

            if($value['unit_price'] < 0) {
                return ['code' => 1, 'msg' => '物料单价只能为正数', 'data' => ''];
            }

//            if($value['num'] < 1) {
//                return ['code' => 1, 'msg' => '采购数量最少为1', 'data' => ''];
//            }

            $materielContent[$key]['materiel_id'] = $materielId;
            $materielContent[$key]['purchase_time'] = $purchaseTime;
            $materielContent[$key]['user_id'] = $userId;
            $materielContent[$key]['main_id'] = $parentId;
            $materielContent[$key]['rest_num'] = $value['num'];
        }

        MaterielContentModel::insert($materielContent);

        return true;
    }

    static public function materielInStorage($data)
    {
        $content = json_decode($data['content'], true);

        //采购单基础信息
        $materielInfo = MaterielModel::where('id', $content[0]['materiel_id'])->first();

        if($materielInfo['repeal_status']) {
            return ['0' => 1, 'msg' => '采购单已撤销，无法重复操作', 'data' => ''];
        }

        if($materielInfo['in_storage_status'] == 2) {
            return ['0' => 1, 'msg' => '已全部入库，无法重复操作', 'data' => ''];
        }

        //status:入库状态：2-全部 1-部分
        switch($data['status']) {
            case 1:
                $result = self::partInStorage($data, $content, $materielInfo);
                break;
            case 2:
                $result = self::partAllStorage($data, $content, $materielInfo);
                break;
        }

        return $result;
    }

    //部分入库
    static public function partInStorage($data, $content, $materielInfo)
    {
        $newStorageArr = [];//库存中不存在商品信息
        $existStorageArr = [];//库存中已存在商品信息
        $materielSerialNumberArr=[];//采购单序列号信息
        $storageManageArr=[];
        foreach($content as $value) {
            $materielContentInfo = MaterielContentModel::getInfo($value['materiel_content_id']);

            $storageInfo = StorageModel::where('id', $value['storage_id'])->first();

            if(empty($storageInfo) || $storageInfo['delete_flag'] == 1) {

                return ['code'=>1,'msg'=>'仓库不存在,无法入库','data'=>''];
            }

//            if($materielContentInfo['rest_num'] < $value['num']) {
//                throw new Exception('商品:'.$materielContentInfo['materiel_name'].'-'.$materielContentInfo['type_name'].'可入库数量不足,无法完成入库,当前可操作数量:('.$materielContentInfo['rest_num'].')');
//            }

//            $storageManageInfo = StorageManageModel::getInfo(
//                $materielContentInfo['second_class_id'],
//                $materielContentInfo['type_id'],
//                $value['storage_id'],
//                $data['main_id'],
//            );
            $value['shelf_id']=empty($value['shelf_id'])?0:$value['shelf_id'];
            $value['location_id']=empty($value['location_id'])?0:$value['location_id'];

            if($data['is_use_shelf']) {
                $storageManageInfo = StorageManageModel::new_getInfo(
                    $materielContentInfo['second_class_id'],
                    $materielContentInfo['type_id'],
                    $value['storage_id'],
                    $data['main_id'],
                    $value['shelf_id'],
                    $value['location_id']
                );
            }
            else {
                $storageManageInfo = StorageManageModel::getInfo(
                    $materielContentInfo['second_class_id'],
                    $materielContentInfo['type_id'],
                    $value['storage_id'],
                    $data['main_id'],
                );
            }

            if(!empty($materielContentInfo['type_id'])){
                $materielTypeInfo = MaterielsTypeModel::where('id', $materielContentInfo['type_id'])->first();
                if(!empty($materielTypeInfo)){
                    if($materielTypeInfo['is_use_serial'] == 1){
                        if(empty($value['serial_no'])){
                            return ['code'=>1,'msg'=>$materielTypeInfo['materiel_name'].'的序列号，不能为空！','data'=>''];
                        }
                    }
                }
            }
            if(empty($storageManageInfo)) {
                $meanPirce = 0;

                if($materielTypeInfo['cost'] != 0) {
                    $meanPirce = sprintf("%.6f",
                        (
                            ($materielTypeInfo['cost'] * 0)
                            +
                            ($value['num'] * $value['price'])
                        )
                        /
                        ($value['num']));
                }
                else {
                    $meanPirce = $value['price'];
                }

                $newStorageArr[] = [
                    'materiel_content_id' => $materielContentInfo['id'],
                    'materiel_class_id' => $materielContentInfo['second_class_id'],
                    'materiel_class_name' => $materielContentInfo['second_class_name'],
                    'materiel_class_no' => $materielContentInfo['second_class_no'],
                    'type_id' => $materielContentInfo['type_id'],
                    'materiel_name' => $materielContentInfo['materiel_name'],
                    'type_name' => $materielContentInfo['type_name'],
                    'materiel_no' => $materielContentInfo['materiel_no'],
                    'materiel_mean_cost' => $meanPirce,
                    'storage_id' => $storageInfo['id'],
                    'storage_name' => $storageInfo['storage_name'],
                    'storage_address' => $storageInfo['storage_address'],
                    'in_storage_num' => $value['num'],
                    'virtual_storage_num' => $value['num'],
                    'remark' => empty($value['remark'])?'':$value['remark'],
                    'main_id' => $data['main_id'],
                    'serial_no'=>!empty($value['serial_no'])?$value['serial_no']:"",
                    'shelf_id' => $value['shelf_id'],
                    'location_id' => $value['location_id'],

                ];
            }
            else {
                $meanPirce = sprintf("%.6f",
                    (
                        ($storageManageInfo['materiel_mean_cost'] * $storageManageInfo['in_storage_num'])
                        +
                        ($value['num'] * $value['price'])
                    )
                    /
                    ($storageManageInfo['in_storage_num'] + $value['num']));

                $existStorageArr[] = [
                    'storage_manage_id' => $storageManageInfo['id'],
                    'in_storage_num' => $value['num'],
                    'materiel_mean_cost' => $meanPirce,
                    'materiel_content_id' => $materielContentInfo['id'],
                    'materiel_class_id' => $materielContentInfo['second_class_id'],
                    'materiel_class_name' => $materielContentInfo['second_class_name'],
                    'materiel_class_no' => $materielContentInfo['second_class_no'],
                    'type_id' => $materielContentInfo['type_id'],
                    'materiel_name' => $materielContentInfo['materiel_name'],
                    'type_name' => $materielContentInfo['type_name'],
                    'materiel_no' => $materielContentInfo['materiel_no'],
                    'storage_id' => $storageInfo['id'],
                    'storage_name' => $storageInfo['storage_name'],
                    'storage_address' => $storageInfo['storage_address'],
                    'virtual_storage_num' => $storageManageInfo['virtual_storage_num'],
                    'main_id' => $data['main_id'],
                    'in_storage_time' => time(),
                    'remark' => empty($value['remark'])?'':$value['remark'],
                    'created_at' => time(),
                    'curr_storage_num' => $storageManageInfo['in_storage_num'],
                    'serial_no'=>!empty($value['serial_no'])?$value['serial_no']:"",
                    'shelf_id' => $storageManageInfo['shelf_id'],
                    'location_id' => $storageManageInfo['location_id']
                ];
            }
            //添加采购序列号
            if(!empty($value['serial_no'])){

                $scondition['type_id'] = $materielContentInfo['type_id'];
                $scondition['materiel_content_id'] = $materielContentInfo['id'];

                $info = MaterielSerialNumberModel::select('serial_no')->where($scondition)->first();
                $serialNoArr01 = explode(',',$value['serial_no']);

                if($value['num'] > count($serialNoArr01)) {
                    return ['code' => 1, 'msg' => '商品:'.$materielContentInfo['materiel_name'].'所需序列号数量不足,'.'仍缺少:'.($value['num'] - count($serialNoArr01)), 'data' => ''];
                }

                if($value['num'] < count($serialNoArr01)) {
                    return ['code' => 1, 'msg' => '商品:'.$materielContentInfo['materiel_name'].'序列号超出实际所需数量,'.'超出:'.(count($serialNoArr01) - $value['num']), 'data' => ''];
                }

                if(!empty($info['serial_no'])){

                    $serialNoArr02 = explode(',',$info['serial_no']);

                    $res = array_intersect($serialNoArr01,$serialNoArr02);

                    if(!empty($res)){

                        return ['code' => 1, 'msg' => '序列号，不允许重复', 'data' => ''];
                    }
                }

                if(!empty($storageManageInfo['id'])){
                        foreach ($serialNoArr01 as $v1){

                            $info = SerialNumberModel::select('a.serial_no')
                            ->from('serial_number as a')
                            ->leftJoin('storage_manage as b','b.id','=','a.storage_manage_id')
                            ->where([
                                'serial_no' => $v1,
                                'goods_id'   => $materielContentInfo['type_id']
                                ])->first();
                            if(!empty($info)){

                                return ['code' => 1, 'msg' => '序列号:'.$v1.'已存在', 'data' => ''];
                            }

                            $storageManageArr[]= [
                            'serial_no'         => $v1,
                            'goods_id'          => $materielContentInfo['type_id'],
                            'storage_manage_id' => $storageManageInfo['id'],
                            'created_at'        => time(),
                                'main_id' => $data['main_id'],
                            ];
                        }
                }

                $materielSerialNumberArr[] = [
                    'serial_no' => $value['serial_no'],
                    'type_id'   => $materielContentInfo['type_id'],
                    'materiel_content_id' => $materielContentInfo['id']
                ];

            }
        }

        DB::beginTransaction();

        try {
            $existLogInfo = [];
            if(!empty($existStorageArr)) {
                foreach($existStorageArr as $existVal) {
                    StorageManageModel::where('id', $existVal['storage_manage_id'])
                        ->update([
                            'in_storage_num' => $existVal['curr_storage_num'] + $existVal['in_storage_num'],
                            'virtual_storage_num' => $existVal['virtual_storage_num'] + $existVal['in_storage_num'],
                            'delete_flag' => 0
                        ]);

                    StorageManageModel::where('type_id', $existVal['type_id'])->update([
                        'materiel_mean_cost' => $existVal['materiel_mean_cost'],
                    ]);

                    $materielTypeInfo = MaterielsTypeModel::where('id', $existVal['type_id'])
                        ->first();

                    MaterielsTypeModel::where('id', $existVal['type_id'])
                        ->update([
                            'cost' => $existVal['materiel_mean_cost'],
                            'last_cost' => $materielTypeInfo['cost'],
                        ]);

                    MaterielContentModel::where('id', $existVal['materiel_content_id'])->decrement('rest_num', $existVal['in_storage_num']);

                    $batchNo = $data['batch_title'].date('YmdHis', time()) .mt_rand(1000, 9999).'0';

                    do {
                        $batchNo = $data['batch_title'].date('YmdHis', time()).mt_rand(1000, 9999).'0';
                    }
                    while(!empty(StorageBatchModel::where('main_id', $data['main_id'])
                        ->where('batch_no', $batchNo)->first()));

                    $batchId = MaterielService::createBatchInfoGetId(
                        $batchNo,
                        $existVal['storage_manage_id'],
                        $existVal['materiel_mean_cost'],
                        $existVal['in_storage_num'],
                        0,
                        $data['main_id']
                    );

                    $existLogInfo[] = [
                        'type' => 0,
                        'storage_id' => $existVal['storage_id'],
                        'storage_name' => $existVal['storage_name'],
                        'storage_address' => $existVal['storage_address'],
                        'curr_storage_manage_id' => $existVal['storage_manage_id'],
                        'materiel_class_id' => $existVal['materiel_class_id'],
                        'materiel_class_name' => $existVal['materiel_class_name'],
                        'materiel_class_no' => $existVal['materiel_class_no'],
                        'materiel_type_id' => $existVal['type_id'],
                        'materiel_name' => $existVal['materiel_name'],
                        'type_name' => $existVal['type_name'],
                        'materiel_no' => $existVal['materiel_no'],
                        'purchase_no' => $materielInfo['purchase_no'],
                        'operate_num' => $existVal['in_storage_num'],
                        'last_storage_num' => $existVal['curr_storage_num'],
                        'next_storage_num' => $existVal['in_storage_num'] + $existVal['curr_storage_num'],
                        'materiel_mean_cost' => $existVal['materiel_mean_cost'],
                        'remark' => empty($existVal['remark'])?'':$existVal['remark'],
                        'batch_id' => $batchId,
                        'all_id_type' => 3,
                        'all_id' => $materielInfo['id'],
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'in_storage_time' => strtotime($data['in_storage_time']),
                        'created_at' => time(),
                        'serial_number'=>$existVal['serial_no'],
                        'shelf_id' => $existVal['shelf_id'],
                        'location_id' => $existVal['location_id']
                    ];

                    MessageService::sendInSms(
                        $materielInfo['purchase_no'],
                        $existVal['materiel_name'],
                        $existVal['type_name'],
                        $existVal['storage_id'],
                        $existVal['storage_name'],
                        $data,
                        $existVal['in_storage_num'],
                        $existVal['in_storage_num'] + $existVal['curr_storage_num']
                    );
                }
            }

            $newLogInfo = [];
            if(!empty($newStorageArr)) {
                foreach($newStorageArr as $newVal) {
                    $newId = StorageManageModel::insertGetId([
                        'materiel_class_id' => $newVal['materiel_class_id'],
                        'materiel_class_name' => $newVal['materiel_class_name'],
                        'materiel_class_no' => $newVal['materiel_class_no'],
                        'type_id' => $newVal['type_id'],
                        'materiel_name' => $newVal['materiel_name'],
                        'type_name' => $newVal['type_name'],
                        'materiel_no' => $newVal['materiel_no'],
                        'materiel_mean_cost' => $newVal['materiel_mean_cost'],
                        'storage_id' => $newVal['storage_id'],
                        'storage_name' => $newVal['storage_name'],
                        'storage_address' => $newVal['storage_address'],
                        'in_storage_num' => $newVal['in_storage_num'],
                        'virtual_storage_num' => $newVal['in_storage_num'],
                        'main_id' => $newVal['main_id'],
                        'in_storage_time' => time(),
                        'created_at' => time(),

                        'shelf_id' => $newVal['shelf_id'],
                        'location_id' => $newVal['location_id']
                    ]);

                    $batchNo = $data['batch_title'].date('YmdHis', time()) .mt_rand(1000, 9999).'0';

                    do {
                        $batchNo = $data['batch_title'].date('YmdHis', time()) .mt_rand(1000, 9999).'0';
                    }
                    while(!empty(StorageBatchModel::where('main_id', $data['main_id'])
                        ->where('batch_no', $batchNo)->first()));

                    $batchId = MaterielService::createBatchInfoGetId(
                        $batchNo,
                        $newId,
                        $newVal['materiel_mean_cost'],
                        $newVal['in_storage_num'],
                        0,
                        $data['main_id']
                    );

                    MaterielsTypeModel::where('id', $newVal['type_id'])
                        ->update(['cost' => $newVal['materiel_mean_cost']]);

                    MessageService::sendInSms(
                        $materielInfo['purchase_no'],
                        $newVal['materiel_name'],
                        $newVal['type_name'],
                        $newVal['storage_id'],
                        $newVal['storage_name'],
                        $data,
                        $newVal['in_storage_num'],
                        $newVal['in_storage_num'],
                    );

                    MaterielContentModel::where('id', $newVal['materiel_content_id'])
                        ->decrement('rest_num', $newVal['in_storage_num']);

                    $newLogInfo[] = [
                        'type' => 0,
                        'storage_id' => $newVal['storage_id'],
                        'storage_name' => $newVal['storage_name'],
                        'storage_address' => $newVal['storage_address'],
                        'curr_storage_manage_id' => $newId,
                        'materiel_class_id' => $newVal['materiel_class_id'],
                        'materiel_class_name' => $newVal['materiel_class_name'],
                        'materiel_class_no' => $newVal['materiel_class_no'],
                        'materiel_type_id' => $newVal['type_id'],
                        'materiel_name' => $newVal['materiel_name'],
                        'type_name' => $newVal['type_name'],
                        'materiel_no' => $newVal['materiel_no'],
                        'purchase_no' => $materielInfo['purchase_no'],
                        'operate_num' => $newVal['in_storage_num'],
                        'last_storage_num' => 0,
                        'batch_id' => $batchId,
                        'next_storage_num' => $newVal['in_storage_num'],
                        'materiel_mean_cost' => $newVal['materiel_mean_cost'],
                        'remark' => isset($newVal['remark'])?'':$newVal['remark'],
                        'all_id_type' => 3,
                        'all_id' => $materielInfo['id'],
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'in_storage_time' => strtotime($data['in_storage_time']),
                        'created_at' => time(),
                        'serial_number'=>$newVal['serial_no'],
                        'shelf_id' => $newVal['shelf_id'],
                        'location_id' => $newVal['location_id']
                    ];

                    //添加采购序列号
                    if(!empty($newVal['serial_no'])){

                        $scondition['type_id'] = $newVal['type_id'];
                        $scondition['materiel_content_id'] = $materielContentInfo['id'];

                        $info = MaterielSerialNumberModel::select('serial_no')->where($scondition)->first();
                        $serialNoArr01 = explode(',',$value['serial_no']);
                        if(!empty($info['serial_no'])){

                            $serialNoArr02 = explode(',',$info['serial_no']);

                            $res = array_intersect($serialNoArr01,$serialNoArr02);

                            if(!empty($res)){

                                return ['code' => 1, 'msg' => '采购序列号，不允许重复', 'data' => ''];
                            }
                        }

                            foreach ($serialNoArr01 as $v1){
                                $info = SerialNumberModel::select('a.serial_no')
                                ->from('serial_number as a')
                                ->leftJoin('storage_manage as b','b.id','=','a.storage_manage_id')
                                ->where([
                                    'serial_no' => $v1,
                                    'a.main_id'   => $data['main_id']
                                ])->first();

                                if(!empty($info)){

                                    return ['code' => 1, 'msg' => '序列号已存在。', 'data' => ''];
                                }
                                $storageManageArr[]= [
                                    'serial_no'         => $v1,
                                    'goods_id'          => $newVal['type_id'],
                                    'storage_manage_id' => $newId,
                                    'created_at'        => time(),
                                    'main_id' => $data['main_id'],
                                ];
                            }
                    }

                }
            }

            if(!empty($newLogInfo)) {
                LogInstorageModel::insert($newLogInfo);
            }

            if(!empty($existLogInfo)) {
                LogInstorageModel::insert($existLogInfo);
            }

            $checkRestNum = MaterielContentModel::where('materiel_id', $materielInfo['id'])
                ->where('rest_num', '!=', 0)->get()->toArray();

            if(empty($checkRestNum)) {
                $status = 2;
                CheckModel::where([
                    'type' => 3,
                    'all_id' => $materielInfo['id'],
                    'main_id' => $data['main_id']
                ])->update([
                    'status' => 1,
                    'out_in_status' => 0
                ]);
            }
            else {
                $status = 1;

                CheckModel::where([
                    'type' => 3,
                    'all_id' => $materielInfo['id'],
                    'main_id' => $data['main_id']
                ])->update([
                    'out_in_status' => 1
                ]);
            }

            MaterielModel::where('id', $materielInfo['id'])->update(['in_storage_status' => $status]);
            if(!empty($materielSerialNumberArr)){
                MaterielSerialNumberModel::insert($materielSerialNumberArr);
            }

            if(!empty($storageManageArr)){
                SerialNumberModel::insert($storageManageArr);
            }
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(Exception $e) {
            DB::rollBack();
            Log::debug('部分采购入库异常:'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //全部入库
    static public function partAllStorage($data, $content, $materielInfo)
    {
        $newStorageArr = [];//库存中不存在商品信息
        $existStorageArr = [];//库存中已存在商品信息
        $materielSerialNumberArr=[];//采购单序列号信息
        $storageManageArr=[];
        foreach($content as $value) {
            $materielContentInfo = MaterielContentModel::select(
                'a.id',
                'a.type_id',
                'a.rest_num',
                'b.materiel_name',
                'b.type_name',
                'b.materiel_no',
                'b.materiel_img',
                'c.id as second_class_id',
                'c.class_name as second_class_name',
                'c.class_no as second_class_no',
                'd.id as first_class_id',
                'd.class_name as first_class_name',
                'e.purchase_no'
            )
                ->from('materiel_content as a')
                ->leftJoin('materiel_type as b', 'b.id', '=', 'a.type_id')
                ->leftJoin('materiel_class as c', 'c.id', '=', 'b.materiel_class_id')
                ->leftJoin('materiel_class as d', 'd.id', '=', 'c.parent_id')
                ->leftJoin('materiel as e', 'e.id', '=', 'a.materiel_id')
                ->where('a.id', $value['materiel_content_id'])
                ->first();

            $storageInfo = StorageModel::where('id', $value['storage_id'])->first();

            if(empty($storageInfo) || $storageInfo['delete_flag'] == 1) {
                return ['code' => 1, 'msg' => '仓库不存在,无法入库', 'data' => ''];
            }

            $storageManageInfo = StorageManageModel::where([
                'materiel_class_id' => $materielContentInfo['second_class_id'],
                'type_id' => $materielContentInfo['type_id'],
                'storage_id' => $value['storage_id'],
                'main_id' => $data['main_id'],
            ])->first();

            if(!empty($materielContentInfo['type_id'])){
                $materielTypeInfo = MaterielsTypeModel::where('id', $materielContentInfo['type_id'])->first();
                if(!empty($materielTypeInfo)){
                    if($materielTypeInfo['is_use_serial'] == 1){
                        if(empty($value['serial_no'])){
                            return ['code'=>1,'msg'=>'商品'.$materielTypeInfo['materiel_name'].'的序列号，不能为空！','data'=>''];
                        }
                    }
                }
            }

            if(empty($storageManageInfo) || $storageManageInfo['delete_flag'] == 1) {
                $materielTypeInfo = MaterielsTypeModel::where('id', $materielContentInfo['type_id'])->first();

                $meanPirce = 0;
                $num = $value['num'] == 0?1:$value['num'];
                if($materielTypeInfo['cost'] != 0) {
                    $meanPirce = sprintf("%.6f",
                        (
                            ($materielTypeInfo['cost'] * $value['num'])
                            +
                            ($value['num'] * $value['price'])
                        )
                        / $num);
                }
                else {
                    $meanPirce = $value['price'];
                }

                $newStorageArr[] = [
                    'materiel_content_id' => $materielContentInfo['id'],
                    'materiel_class_id' => $materielContentInfo['second_class_id'],
                    'materiel_class_name' => $materielContentInfo['second_class_name'],
                    'materiel_class_no' => $materielContentInfo['second_class_no'],
                    'type_id' => $materielContentInfo['type_id'],
                    'materiel_name' => $materielContentInfo['materiel_name'],
                    'type_name' => $materielContentInfo['type_name'],
                    'materiel_no' => $materielContentInfo['materiel_no'],
                    'materiel_mean_cost' => $meanPirce,
                    'remark' => empty($value['remark'])?'':$value['remark'],
                    'storage_id' => $storageInfo['id'],
                    'storage_name' => $storageInfo['storage_name'],
                    'storage_address' => $storageInfo['storage_address'],
                    'in_storage_num' => $materielContentInfo['rest_num'],
                    'main_id' => $data['main_id'],
                    'serial_no'=>!empty($value['serial_no'])?$value['serial_no']:""
                ];
            }
            else {
                $meanPirce = sprintf("%.6f",
                    (
                        ($storageManageInfo['materiel_mean_cost'] * $storageManageInfo['in_storage_num'])
                        +
                        ($materielContentInfo['num'] * $value['price'])
                    )
                    /
                    ($storageManageInfo['in_storage_num'] + $materielContentInfo['rest_num']));

                $existStorageArr[] = [
                    'storage_manage_id' => $storageManageInfo['id'],
                    'materiel_mean_cost' => $meanPirce,
                    'materiel_content_id' => $materielContentInfo['id'],
                    'materiel_class_id' => $materielContentInfo['second_class_id'],
                    'materiel_class_name' => $materielContentInfo['second_class_name'],
                    'materiel_class_no' => $materielContentInfo['second_class_no'],
                    'type_id' => $materielContentInfo['type_id'],
                    'materiel_name' => $materielContentInfo['materiel_name'],
                    'type_name' => $materielContentInfo['type_name'],
                    'materiel_no' => $materielContentInfo['materiel_no'],
                    'storage_id' => $storageInfo['id'],
                    'storage_name' => $storageInfo['storage_name'],
                    'storage_address' => $storageInfo['storage_address'],
                    'in_storage_num' => $materielContentInfo['rest_num'],
                    'remark' => empty($value['remark'])?'':$value['remark'],
                    'virtual_storage_num' => $storageManageInfo['virtual_storage_num'],
                    'main_id' => $data['main_id'],
                    'in_storage_time' => time(),
                    'created_at' => time(),
                    'curr_storage_num' => $storageManageInfo['in_storage_num'],
                    'serial_no'=>!empty($value['serial_no'])?$value['serial_no']:""
                ];
            }
            //添加采购序列号
            if(!empty($value['serial_no'])){

                $scondition['type_id'] = $materielContentInfo['type_id'];
                $scondition['materiel_content_id'] = $materielContentInfo['id'];

                $info = MaterielSerialNumberModel::select('serial_no')->where($scondition)->first();
                $serialNoArr02 = explode(',',$info['serial_no']);
                if(!empty($info['serial_no'])){

                    $serialNoArr01 = explode(',',$value['serial_no']);

                    $res = array_intersect($serialNoArr01,$serialNoArr02);

                    if(!empty($res)){

                        return ['code' => 1, 'msg' => '采购序列号，不允许重复', 'data' => ''];
                    }
                }
                if(!empty($storageManageInfo['id'])){
                    foreach ($serialNoArr01 as $v1){
                        $info = SerialNumberModel::select('a.serial_no')
                        ->from('serial_number as a')
                        ->leftJoin('storage_manage as b','b.id','=','a.storage_manage_id')
                        ->where([
                            'serial_no' => $v1,
                            'goods_id'   => $materielContentInfo['type_id']
                        ])->first();
                        if(!empty($info)){

                            return ['code' => 1, 'msg' => '序列号'.$v1.'已存在。', 'data' => ''];
                        }
                        $storageManageArr[]= [
                            'serial_no'         => $v1,
                            'goods_id'          => $materielContentInfo['type_id'],
                            'storage_manage_id' => $storageManageInfo['id'],
                            'created_at'        => time(),
                            'main_id' => $data['main_id'],
                        ];
                    }
                }
                $materielSerialNumberArr[] = [
                    'serial_no' => $value['serial_no'],
                    'type_id'   => $materielContentInfo['type_id'],
                    'materiel_content_id' => $materielContentInfo['id']
                ];
            }
        }

        DB::beginTransaction();

        try {
            $existLogInfo = [];
            if(!empty($existStorageArr)) {
                foreach($existStorageArr as $existVal) {
//                    StorageManageModel::where('type_id', $existVal['type_id'])
//                        ->where(['main_id' => $data['main_id']])
//                        ->increment('in_storage_num', $existVal['in_storage_num'],
//                        ['materiel_mean_cost' => $existVal['materiel_mean_cost']]
//                    );

                    StorageManageModel::where('id', $existVal['storage_manage_id'])
                        ->update([
                            'in_storage_num' => $existVal['curr_storage_num'] + $existVal['in_storage_num'],
                            'virtual_storage_num' => $existVal['virtual_storage_num'] + $existVal['in_storage_num'],
                            'delete_flag' => 0
                        ]);

                    StorageManageModel::where('type_id', $existVal['type_id'])->update([
                        'materiel_mean_cost' => $existVal['materiel_mean_cost'],
                    ]);

                    MaterielsTypeModel::where('id', $existVal['type_id'])
                        ->update(['cost' => $existVal['materiel_mean_cost']]);

                    MaterielContentModel::where('id', $existVal['materiel_content_id'])->decrement('rest_num', $existVal['in_storage_num']);

                    $batchNo = $data['batch_title'].date('YmdHis', time()) .mt_rand(1000, 9999).'0';

                    do {
                        $batchNo = $data['batch_title'].date('YmdHis', time()).mt_rand(1000, 9999).'0';
                    }
                    while(!empty(StorageBatchModel::where('main_id', $data['main_id'])
                        ->where('batch_no', $batchNo)->first()));

                    $existLogInfo[] = [
                        'type' => 0,
                        'storage_id' => $existVal['storage_id'],
                        'storage_name' => $existVal['storage_name'],
                        'storage_address' => $existVal['storage_address'],
                        'curr_storage_manage_id' => $existVal['storage_manage_id'],
                        'materiel_class_id' => $existVal['materiel_class_id'],
                        'materiel_class_name' => $existVal['materiel_class_name'],
                        'materiel_class_no' => $existVal['materiel_class_no'],
                        'materiel_type_id' => $existVal['type_id'],
                        'materiel_name' => $existVal['materiel_name'],
                        'type_name' => $existVal['type_name'],
                        'materiel_no' => $existVal['materiel_no'],
                        'purchase_no' => $materielInfo['purchase_no'],
                        'operate_num' => $existVal['in_storage_num'],
                        'last_storage_num' => $existVal['curr_storage_num'],
                        'next_storage_num' => $existVal['in_storage_num'] + $existVal['curr_storage_num'],
                        'materiel_mean_cost' => $existVal['materiel_mean_cost'],
                        'remark' => empty($existVal['remark'])?'':$existVal['remark'],
                        'all_id_type' => 3,
                        'batch_no' => $batchNo,
                        'all_id' => $materielInfo['id'],
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'in_storage_time' => strtotime($data['in_storage_time']),
                        'created_at' => time(),
                        'serial_number'=>$existVal['serial_no']
                    ];

                    self::createBatchInfo(
                        $batchNo,
                        $existVal['storage_manage_id'],
                        $existVal['materiel_mean_cost'],
                        $existVal['in_storage_num'],
                        $materielInfo['id'],
                        $data['main_id']
                    );

                    MessageService::sendInSms(
                        $materielInfo['purchase_no'],
                        $existVal['materiel_name'],
                        $existVal['type_name'],
                        $existVal['storage_id'],
                        $existVal['storage_name'],
                        $data,
                        $existVal['in_storage_num'],
                        $existVal['in_storage_num']
                    );
                }
            }

            $newLogInfo = [];
            if(!empty($newStorageArr)) {
                foreach($newStorageArr as $newVal) {
                    $newId = StorageManageModel::insertGetId([
                        'materiel_class_id' => $newVal['materiel_class_id'],
                        'materiel_class_name' => $newVal['materiel_class_name'],
                        'materiel_class_no' => $newVal['materiel_class_no'],
                        'type_id' => $newVal['type_id'],
                        'materiel_name' => $newVal['materiel_name'],
                        'type_name' => $newVal['type_name'],
                        'materiel_no' => $newVal['materiel_no'],
                        'materiel_mean_cost' => $newVal['materiel_mean_cost'],
                        'storage_id' => $newVal['storage_id'],
                        'storage_name' => $newVal['storage_name'],
                        'storage_address' => $newVal['storage_address'],
                        'in_storage_num' => $newVal['in_storage_num'],
                        'virtual_storage_num' =>  $newVal['in_storage_num'],
                        'main_id' => $newVal['main_id'],
                        'in_storage_time' => time(),
                        'created_at' => time()
                    ]);

                    $batchNo = $data['batch_title'].date('YmdHis', time()) .mt_rand(1000, 9999).'0';

                    do {
                        $batchNo = $data['batch_title'].date('YmdHis', time()).mt_rand(1000, 9999).'0';
                    }
                    while(!empty(StorageBatchModel::where('main_id', $data['main_id'])
                        ->where('batch_no', $batchNo)->first()));
                    self::createBatchInfo(
                        $batchNo,
                        $newId,
                        $newVal['materiel_mean_cost'],
                        $newVal['in_storage_num'],
                        $materielInfo['id'],
                        $data['main_id']
                    );

                    StorageManageModel::where('type_id', $newVal['type_id'])->update([
                        'materiel_mean_cost' => $newVal['materiel_mean_cost']
                    ]);

                    MaterielsTypeModel::where('id', $newVal['type_id'])
                        ->update(['cost' => $newVal['materiel_mean_cost']]);

                    MaterielContentModel::where('id', $newVal['materiel_content_id'])->decrement('rest_num', $newVal['in_storage_num']);

                    MessageService::sendInSms(
                        $materielInfo['purchase_no'],
                        $newVal['materiel_name'],
                        $newVal['type_name'],
                        $newVal['storage_id'],
                        $newVal['storage_name'],
                        $data,
                        $newVal['in_storage_num'],
                        $newVal['in_storage_num']
                    );

                    $newLogInfo[] = [
                        'type' => 0,
                        'storage_id' => $newVal['storage_id'],
                        'storage_name' => $newVal['storage_name'],
                        'storage_address' => $newVal['storage_address'],
                        'curr_storage_manage_id' => $newId,
                        'materiel_class_id' => $newVal['materiel_class_id'],
                        'materiel_class_name' => $newVal['materiel_class_name'],
                        'materiel_class_no' => $newVal['materiel_class_no'],
                        'materiel_type_id' => $newVal['type_id'],
                        'materiel_name' => $newVal['materiel_name'],
                        'type_name' => $newVal['type_name'],
                        'materiel_no' => $newVal['materiel_no'],
                        'purchase_no' => $materielInfo['purchase_no'],
                        'operate_num' => $newVal['in_storage_num'],
                        'last_storage_num' => 0,
                        'next_storage_num' => $newVal['in_storage_num'],
                        'materiel_mean_cost' => $newVal['materiel_mean_cost'],
                        'remark' => empty($newVal['remark'])?'':$newVal['remark'],
                        'all_id_type' => 3,
                        'batch_no' => $batchNo,
                        'all_id' => $materielInfo['id'],
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'in_storage_time' => strtotime($data['in_storage_time']),
                        'created_at' => time(),
                        'serial_number'=>$newVal['serial_no']
                    ];

                    //添加采购序列号
                    if(!empty($newVal['serial_no'])){

                        $scondition['type_id'] = $newVal['type_id'];
                        $scondition['materiel_content_id'] = $materielContentInfo['id'];

                        $info = MaterielSerialNumberModel::select('serial_no')->where($scondition)->first();
                        $serialNoArr01 = explode(',',$value['serial_no']);


                        if(!empty($info['serial_no'])){

                            $serialNoArr02 = explode(',',$info['serial_no']);

                            $res = array_intersect($serialNoArr01,$serialNoArr02);

                            if(!empty($res)){

                                return ['code' => 1, 'msg' => '采购序列号，不允许重复', 'data' => ''];
                            }
                        }

                        foreach ($serialNoArr01 as $v1){
                            $info = SerialNumberModel::select('a.serial_no')
                            ->from('serial_number as a')
                            ->leftJoin('storage_manage as b','b.id','=','a.storage_manage_id')
                            ->where([
                                'serial_no' => $v1,
                                'a.main_id'   => $data['main_id']
                            ])->first();
                            if(!empty($info)){

                                return ['code' => 1, 'msg' => '序列号已存在。', 'data' => ''];
                            }
                            $storageManageArr[]= [
                                'serial_no'         => $v1,
                                'goods_id'          => $newVal['type_id'],
                                'storage_manage_id' => $newId,
                                'created_at'        => time(),
                                'main_id' => $data['main_id'],
                            ];
                        }
                    }
                }
            }

            if(!empty($newLogInfo)) {
                LogInstorageModel::insert($newLogInfo);
            }

            if(!empty($existLogInfo)) {
                LogInstorageModel::insert($existLogInfo);
            }

            MaterielModel::where('id', $materielInfo['id'])->update(['in_storage_status' => 2]);

            CheckModel::where([
                'type' => 3,
                'all_id' => $materielInfo['id'],
                'main_id' => $data['main_id']
            ])->update([
                'status' => 1,
                'out_in_status' => 0
            ]);
            if(!empty($materielSerialNumberArr)){
                MaterielSerialNumberModel::insert($materielSerialNumberArr);
            }
            if(!empty($storageManageArr)){
                SerialNumberModel::insert($storageManageArr);
            }
            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(Exception $e) {
            DB::rollBack();
            Log::debug('部分采购入库异常:'.var_export($e->getMessage(), true));
            return [];
        }
    }

    static public function list($data, $userId)
    {
        if(!empty($data['keyword'])) {//关键词搜索组是否启用
            $result = self::withKeyword($userId, $data);
        }
        else {
            $result = self::search($userId, $data);
        }

        return $result;
    }

    static private function withKeyword($userId, $data)
    {
        $materielIdInfo = [];
        switch($data['search_type']) {
            case 0:
                $condition[] = ['b.type_name', 'like', '%'.$data['keyword'].'%'];
                $materielIdInfo = MaterielContentModel::getMaterielId($condition, $userId);
                break;
            //商品名
            case 1:
                $condition[] = ['b.materiel_name', 'like', '%'.$data['keyword'].'%'];
                $materielIdInfo = MaterielContentModel::getMaterielId($condition, $userId);
                break;
            //商品编号
            case 2:
                $condition[] = ['b.materiel_no', 'like', '%'.$data['keyword'].'%'];
                $materielIdInfo = MaterielContentModel::getMaterielId($condition, $userId);
                break;
            //内部单号
            case 3:
                $condition[] = ['purchase_no', 'like', '%'.$data['keyword'].'%'];
                $materielIdInfo = MaterielModel::getMaterielId($condition, $userId);
                break;
            //外部单号
            case 4:
                $condition[] = ['out_order_no', 'like', '%'.$data['keyword'].'%'];
                $materielIdInfo = MaterielModel::getMaterielId($condition, $userId);
                break;
            //快递单号
            case 5:
                $condition[] = ['logistics_order_no', 'like', '%'.$data['keyword'].'%'];
                $materielIdInfo = MaterielModel::getMaterielId($condition, $userId);
                break;
            //供应商
            case 6:
                $condition[] = ['supplier_name', 'like', '%'.$data['keyword'].'%'];
                $materielIdInfo = MaterielModel::getMaterielId($condition, $userId);
                break;
            //司机名称
//            case 7:
//                $condition[] = ['logistics_order_no', 'like', '%'.$data['keyword'].'%'];
//                $materielIdInfo = MaterielsModel::getMaterielId($condition, $userId);
//                break;
            //发货人
            case 8:
                $condition[] = ['deliver_person', 'like', '%'.$data['keyword'].'%'];
                $materielIdInfo = MaterielModel::getMaterielId($condition, $userId);
                break;
        }

        $materielIdArr = [];
        foreach($materielIdInfo as $value) {
            $materielIdArr[] = $value['materiel_id'];
        }

        if(empty($materielIdArr)) {
            $materielIdArr = [''];
        }

        return self::search($userId, $data, $materielIdArr);
    }

    //无搜索条件-默认检索
    static private function search($userId, $data, $materielIdArr = [])
    {
        $query = MaterielModel::select(
            'a.id',
            'repeal_status',
            'purchase_time',
            'supplier_name',
            'final_money',
            'out_order_no',
            'purchase_no',
            'pay_status',
            'in_storage_status',
            'username',
            'nickname'
        )
            ->from('materiel as a')
            ->leftJoin('admin as b', 'b.id', '=', 'a.user_id')
            ->with('materielContent', function($query) {
                $query->select(
                    'materiel_content.id',
                    'materiel_id',
                    'unit_price',
                    'num',
                    'rest_num',
                    'a.materiel_name',
                    'a.type_name',
                    'a.materiel_no',
                    'a.materiel_img',
                    'materiel_content.shelf_id',
                    'materiel_content.location_id',
                    's.shelf_name',
                    'l.location_name',
                )
                    ->leftJoin('materiel_type as a', 'a.id', '=', 'materiel_content.type_id')
                    ->leftJoin('storage_shelf as s','materiel_content.shelf_id','=','s.id')
                    ->leftJoin('storage_shelf_location as l','materiel_content.location_id','=','l.id');
            })
            ->where('repeal_status', $data['repeal_status'])
            ->where('a.delete_flag', 0)
            ->where($userId);

        if(!empty($data['start_time'])) {
            $startTimeArr = explode(' ', $data['start_time']);
            $startTime = strtotime($startTimeArr[0].' 00:00:00');
        }

        if(!empty($data['end_time'])) {
            $endTimeArr = explode(' ', $data['end_time']);
            $endTime = strtotime($endTimeArr[0].' 23:59:59');
        }

        if(!empty($startTime) && !empty($endTime)) {
            $query->whereBetween('purchase_time', [$startTime, $endTime]);
        }
        else if(!empty($startTime) && empty($endTime)) {
            $query->where('purchase_time', '>=', $startTime);
        }
        else if(empty($startTime) && !empty($endTime)) {
            $query->where('purchase_time', '<=', $endTime);
        }

        //销售单状态
        switch($data['status']) {
            //新订单
            case 1:
                $query->where('pay_status', 0);
                $query->where('in_storage_status', 0);
                break;
            //已付款(未入库)
            case 2:
                $query->whereIn('pay_status', [1,2]);
                $query->where('in_storage_status', 0);
                break;
            //已完结（已付款，已入库）
            case 3:
                $query->where('pay_status', 2);
                $query->where('in_storage_status', 2);
                break;
            //已入货(未付款)
            case 4:
                $query->where('pay_status', 0);
                $query->whereIn('in_storage_status', [1,2]);
                break;
        }

        if(!empty($materielIdArr)) {
            $query->whereIn('a.id', $materielIdArr);
        }
        else {
            $query->orWhereIn('a.id', $materielIdArr);
        }

        $query = $query->orderBy('id','desc')
            ->paginate($data['pageSize'],['*'], '',$data['currentPage'])->toArray();

        foreach($query['data'] as &$value) {
            $value['out_order_no'] = empty($value['out_order_no'])?'':$value['out_order_no'];
            foreach($value['materiel_content'] as $v) {
                @$value['total_num'] += $v['num'];
            }
        }

        return $query;
    }

    static public function payHistory($id)
    {
        if(empty(MaterielPayHistoryModel::where('materiel_id', $id)->first())) {
            return '';
        }
        else {
            return MaterielPayHistoryModel::select(
                'a.purchase_no',
                'b.materiel_id',
                'b.money',
                'b.pay_time',
                'b.payer_account',
                'b.main_id',
                'b.created_at'
            )
                ->from('materiel as a')
                ->leftJoin('materiel_pay_history as b', 'a.id', '=', 'b.materiel_id')
                ->where('a.id', $id)
                ->get()->toArray();
        }
    }

    static public function createBatchInfo($batchNo, $storageManageId, $cost, $num, $materielId, $mainId)
    {
        StorageBatchModel::insert([
            'batch_no' => $batchNo,
            'storage_manage_id' => $storageManageId,
            'batch_num' => $num,
            'batch_left_num' => $num,
            'batch_cost' => $cost,
            'materiel_id' => $materielId,
            'main_id' => $mainId,
            'created_at' => time()
        ]);

        return true;
    }

    static public function createBatchInfoGetId($batchNo, $storageManageId, $cost, $num, $materielId, $mainId)
    {
       return StorageBatchModel::insertGetId([
            'batch_no' => $batchNo,
            'storage_manage_id' => $storageManageId,
            'batch_num' => $num,
            'batch_left_num' => $num,
            'batch_cost' => $cost,
            'materiel_id' => $materielId,
            'main_id' => $mainId,
            'created_at' => time()
        ]);
    }

    static public function cancel($mainId, $data)
    {
        $checkMaterielInfo = MaterielModel::where([
            'id' => $data['id'],
            'delete_flag' => 0
        ])->first();

        if(empty($checkMaterielInfo)) {
            return ['code' => 1, 'msg' => '该采购单不存在或已被删除', 'data' => ''];
        }

        if($checkMaterielInfo['repeal_status']) {
            return ['code' => 1, 'msg' => '该采购单已撤销，无法重复操作', 'data' => ''];
        }

        $logInfo = LogInstorageModel::where([
            'all_id_type' => 3,
            'all_id' => $data['id'],
            'is_cancel' => 0
        ])->get()->toArray();

        DB::beginTransaction();

        try {
            if(!empty($logInfo)) {
                foreach($logInfo as $value) {
                    $storageManageInfo = StorageManageModel::select(
                        'a.id',
                        'in_storage_num',
                        'b.materiel_name',
                        'b.type_name',
                        'type_id'
                    )
                        ->from('storage_manage as a')
                        ->leftJoin('materiel_type as b', 'b.id', '=', 'a.type_id')
                        ->where('a.id', $value['curr_storage_manage_id'])->first();

                    if(empty($storageManageInfo)) {
                        return ['code' => 1, 'msg' => '库存信息不存在，无法撤销', 'data' => ''];
                    }

                    if($storageManageInfo['delete_flag']) {
                        return ['code' => 1, 'msg' => '商品：'.$storageManageInfo['materiel_name'].'-'.$storageManageInfo['type_name'].'已被删除，无法完成撤销', 'data' => ''];
                    }

                    if($storageManageInfo['in_storage_num'] < $value['operate_num']) {
                        return [
                            'code' => 1,
                            'msg' => '商品：'.$storageManageInfo['materiel_name'].'-'.$storageManageInfo['type_name'].'库存数不足(当前库存:'.$storageManageInfo['in_storage_num'].',操作数量:'.$value['operate_num'].')，无法完成撤销',
                            'data' => ''];
                    }

                    $storageBatchInfo = StorageBatchModel::where('id', $value['batch_id'])->first();

                    if($value['operate_num'] > $storageBatchInfo['batch_left_num']) {
                        return [
                            'code' => 1,
                            'msg' => '商品：'.$storageManageInfo['materiel_name'].'-'.$storageManageInfo['type_name'].'剩余批次数量不足，无法完成撤销',
                            'data' => ''
                        ];
                    }

                    $materielTypeInfo = MaterielsTypeModel::where('id', $storageManageInfo['type_id'])->first();

                    $materielTypeInfo->cost = $materielTypeInfo['last_cost'];
                    $materielTypeInfo->save();

                    //扣除批次数量
                    $storageBatchInfo->batch_left_num = 0;
                    $storageBatchInfo->save();

                    StorageManageModel::where('id', $value['curr_storage_manage_id'])
                        ->update([
                            'in_storage_num' => DB::raw('in_storage_num - '.$value['operate_num']),
                            'virtual_storage_num' => DB::raw("virtual_storage_num - ".$value['operate_num']),
                            'materiel_mean_cost' => $materielTypeInfo['last_cost'],
                        ]);
                }

                $logInfoId = [];
                foreach($logInfo as $val) {
                    $logInfoId[] = $val['id'];
                }

                LogInstorageModel::whereIn('id', $logInfoId)->update(['is_cancel' => 1]);
            }

            MaterielModel::where('id', $data['id'])->update(['repeal_status' => 1]);
            MaterielContentModel::where('materiel_id', $data['id'])->update(['repeal_status' => 1]);
            CheckModel::where([
                'type' => 3,
                'all_id' => $data['id']
            ])->update(['repeal_status' => 1]);

            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(Exception $e) {
            DB::rollBack();
            Log::debug('采购撤销异常'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //重新下单
    static public function addAgain($userId, $parentId, $data)
    {
        $materielInfo = MaterielModel::where('id', $data['id'])->first()->toArray();
        $materielContentInfo = MaterielContentModel::where('materiel_id', $data['id'])->get()->toArray();

        unset($materielInfo['id']);
        $materielInfo['purchase_no'] = $data['purchase_no'];
        $materielInfo['repeal_status'] = 0;
        $materielInfo['user_id'] = $userId;
        $materielInfo['main_id'] = $parentId;
        $materielInfo['created_at'] = time();
        $materielInfo['updated_at'] = NULL;
        $materielInfo['remark'] = '';
        $materielInfo['pay_status'] = 0;
        $materielInfo['in_storage_status'] = 0;
        $materielInfo['purchase_time'] = time();
        $materielInfo['purchase_date'] = strtotime(date('Y-m-d', strtotime($materielInfo['purchase_time'])));

        DB::beginTransaction();

        try {
            $insertId = MaterielModel::insertGetId($materielInfo);

            foreach($materielContentInfo as $k => $v) {
                unset($materielContentInfo[$k]['id']);
                unset($materielContentInfo[$k]['updated_at']);

                $materielContentInfo[$k]['materiel_id'] = $insertId;
                $materielContentInfo[$k]['rest_num'] = $v['num'];
                $materielContentInfo[$k]['user_id'] = $userId;
                $materielContentInfo[$k]['main_id'] = $parentId;
                $materielContentInfo[$k]['created_at'] = time();
            }

            CheckModel::insert([
                'type' => 3,
                'all_id' => $insertId,
                'main_id' => $parentId,
                'user_id' => $userId,
                'status' => 0,
                'out_in_status' => 0,
                'created_at' => time(),
                'order_no' => $data['purchase_no']
            ]);

            MaterielContentModel::insert($materielContentInfo);
            DB::commit();
            return '';
        } catch (Exception $e) {
            DB::rollBack();
            Log::debug('采购重新下单:'.var_export($e->getMessage(), true));
        }
    }

    //删除指定采购
    static public function del($data)
    {
        $materielInfo = MaterielModel::where('id', $data['id'])->first();

        if($materielInfo['pay_status'] == 1 || $materielInfo['in_storage_status'] == 1) {
            return ['code' => 1, 'msg' => '无法删除，请检查此采购单状态', 'data' => ''];
        }

        MaterielModel::where('id', $data['id'])->update(['delete_flag' => 1]);
        CheckModel::where('type', 3)->where('all_id', $data['id'])->update(['repeal_status' => 1]);

        return ['code' => 0, 'msg' => 'success', 'data' => ''];
    }

    //详细
    static public function detail($datas)
    {
        $data = MaterielModel::select(
            'a.*',
            'b.nickname',
            'b.username',
        )
            ->with('materielContent', function($query) {
                $query->select(
                    'materiel_content.id',
                    'materiel_content.type_id',
                    'materiel_id',
                    'unit_price',
                    'num',
                    'materiel_content.rest_num',
                    'a.materiel_name',
                    'a.type_name',
                    'a.materiel_no',
                    'a.materiel_img',
                    'materiel_content.storage_id',
                    'b.storage_name',
                    'b.storage_address',
                    'a.is_use_serial',
                    'materiel_content.shelf_id',
                    'materiel_content.location_id',
                    's.shelf_name',
                    'l.location_name',
                )
                    ->leftJoin('materiel_type as a', 'a.id', '=', 'materiel_content.type_id')
                    ->leftJoin('storage as b', 'b.id', '=', 'materiel_content.storage_id')
                    ->leftJoin('storage_shelf as s','materiel_content.shelf_id','=','s.id')
                    ->leftJoin('storage_shelf_location as l','materiel_content.location_id','=','l.id');
//                                ->leftJoin('storage_manage as c', 'c.id', '=', 'materiel_content.storage_manage_id');
            })
            ->from('materiel as a')
            ->leftJoin('admin as b', 'b.id', '=', 'a.user_id')
            ->where('a.id', $datas['id'])
            ->where('a.delete_flag', 0)
            ->orderBy('a.id', 'desc')
            ->get()->toArray();

        foreach($data as $key => $value) {
            foreach($value['materiel_content'] as $k => $val) {
                $data[$key]['materiel_content'][$k]['in_num'] = $val['num'] - $val['rest_num'];
                $data[$key]['materiel_content'][$k]['is_in'] = $val['num'] == $val['rest_num']?0:1;

                if($val['is_use_serial'] == 1){
                    $snCondition['type_id']=$val['type_id'];
                    $snCondition['materiel_content_id']=$val['id'];

                    $list = MaterielSerialNumberModel::select('serial_no')->where($snCondition)->get()->toArray();
                    $data[$key]['materiel_content'][$k]['serial_number_list']=[];

                    if(!empty($list)){
                        $str="";
                        foreach($list as $v){
                            $str .= $v['serial_no'].',';
                        }
                        $str = substr($str,0,strrpos($str,","));

                        $data[$key]['materiel_content'][$k]['serial_number_list'] = explode(',', $str);
                    }
                }
            }
        }
        return empty($data[0])?[]:$data[0];
    }

    //添加采购但其他费用
    static public function addCharges($data)
    {
        //开启事务
        DB::beginTransaction();
        try{
            MaterielOtherChargesModel::insert($data);
            $model = MaterielModel::where('id',$data['materiel_id'])->first();
            $model->final_money += $data['money'];
            $model->other_charges = $model->other_charges+$data['money'];
            $model->save();

            DB::commit();//提交事务
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }catch (Exception $e){
            DB::rollBack();//事务回滚
            //异常响应
            Log::debug('添加其他费用:'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //编辑其他费用
    static public function editCharges($data)
    {
        //开启事务
        DB::beginTransaction();
        try{
            $beforeModel = MaterielOtherChargesModel::where('id',$data['id'])->first();
            MaterielOtherChargesModel::where('id',$data['id'])->update($data);
            $beforeMoney = $beforeModel['money'];
            $final = $data['money'] - $beforeMoney;
            $model = MaterielModel::where('id',$beforeModel['materiel_id'])->first();
            $model->final_money += $final;
            $model->other_charges = $model->other_charges+$final;
            $model->save();
            DB::commit();//提交事务
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }catch (Exception $e){
            DB::rollBack();//事务回滚
            //异常响应
            Log::debug('编辑其他费用:'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //付款
    static public function payMaterielMoney($data)
    {
        unset($data['status']);
        $materielInfo = MaterielModel::where('id',$data['materiel_id'])->first();//销售单信息
        $paidMomey = MaterielPayHistoryModel::where('materiel_id',$data['materiel_id'])->sum('money');//已收款金额

        $payInfo = MaterielPayHistoryModel::where('materiel_id',$data['materiel_id'])->first();

        if($materielInfo['pay_status'] == 2) {
            return ['0' => 0, 'msg' => '支付已完成，无需重复支付', 'data' => ''];
        }

        //支付后实付金额
        $afterPayMoney = sprintf('%.6f', ($paidMomey + $data['money']));

        if($afterPayMoney > $materielInfo['final_money']) {
            return ['code' => 1, 'msg' => '超出实际应付金额，请重试', 'data' => ''];
        }

        $payStatus = 1;
        if($afterPayMoney == $materielInfo['final_money']) {
            $payStatus = 2;
        }

        DB::beginTransaction();

        try {
            if(empty($payInfo)) {
                MaterielModel::where('id', $data['materiel_id'])
                    ->update([
                        'fact_money' => 0
                    ]);
            }

            $tallyContent = TallyClassModel::where('id', 753)->first();

            TallyModel::insert([
                'tally_class_id' => $tallyContent['id'],
                'tally_class_name' => $tallyContent['name'],
                'type' => 1,
                'money' => $data['money'],
                'order_no' => $materielInfo['purchase_no'],
                'main_id' => $data['main_id'],
                'add_time' => strtotime($materielInfo['purchase_time']),
                'created_at' => time()
            ]);

            MaterielModel::where('id', $data['materiel_id'])->increment('fact_money', $data['money'], [
                'pay_status' => $payStatus
            ]);
            $data['purchase_no'] = $materielInfo['purchase_no'];
            MaterielPayHistoryModel::insert($data);

            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch (\Exception $e) {
            DB::rollBack();
            Log::debug('采购付款异常:'.$e->getMessage());
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }
}
